﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using CommonLib;
using Microsoft.Xna.Framework;

namespace VectorOperationBenchmark {
    class Program {
        public const uint LOOP = 1000 * 1000 * 100;
        public const uint REPEAT = 3;
        public static Stopwatch swatch = new Stopwatch();
        static void Main(string[] args) {
            Console.WriteLine("Loops=" + LOOP);

            for (uint i = 0; i < REPEAT; i++) {
                testXNA();
                testVector3c();
            }

            Console.Out.Flush();
            int ch = Console.In.Read();
        }
        public static void testXNA() {
            // diag
            Console.WriteLine("==== Test XNA Vector3 ====");
            Vector3 sumc;
            Vector3 biasc = new Vector3(1.0f, 1.0f, 1.0f);
            Vector3 gainc = new Vector3(1.0f, 1.0f, 1.0f);
            Vector3 elemc = new Vector3(1.0f, 1.0f, 1.0f);

            // add
            sumc = new Vector3();
            swatch.Reset();
            swatch.Start();
            for (uint i = 0; i < LOOP; i++) {
                //sumc += elemc;
                Vector3 tmp = elemc + biasc;
            }
            swatch.Stop();
            Console.WriteLine("Add\t" + swatch.Elapsed);

            // sub
            sumc = new Vector3();
            swatch.Reset();
            swatch.Start();
            for (uint i = 0; i < LOOP; i++) {
                //sumc -= elemc;
                Vector3 tmp = elemc - biasc;
            }
            swatch.Stop();
            Console.WriteLine("Sub\t" + swatch.Elapsed);

            // mul
            sumc = elemc;
            swatch.Reset();
            swatch.Start();
            for (uint i = 0; i < LOOP; i++) {
                //sumc *= gainc;
                Vector3 tmp = elemc * gainc;
            }
            swatch.Stop();
            Console.WriteLine("Mul\t" + swatch.Elapsed);

            // div
            sumc = elemc;
            swatch.Reset();
            swatch.Start();
            for (uint i = 0; i < LOOP; i++) {
                //sumc /= gainc;
                Vector3 tmp = elemc / gainc;
            }
            swatch.Stop();
            Console.WriteLine("Div\t" + swatch.Elapsed);

            //mac
            sumc = new Vector3();
            swatch.Reset();
            swatch.Start();
            for (uint i = 0; i < LOOP; i++) {
                sumc += gainc * elemc;
            }
            swatch.Stop();
            Console.WriteLine("Mac\t" + swatch.Elapsed);

            // dot
            double dotc;
            swatch.Reset();
            swatch.Start();
            for (uint i = 0; i < LOOP; i++) {
                dotc = Vector3.Dot(elemc, gainc);
            }
            swatch.Stop();
            Console.WriteLine("Dot\t" + swatch.Elapsed);

            // norm
            float distc;
            swatch.Reset();
            swatch.Start();
            for (uint i = 0; i < LOOP; i++) {
                distc = elemc.Length();
            }
            swatch.Stop();
            Console.WriteLine("Norm\t" + swatch.Elapsed);

            // normalize
            sumc = elemc;
            swatch.Reset();
            swatch.Start();
            for (uint i = 0; i < LOOP; i++) {
                sumc.Normalize();
            }
            swatch.Stop();
            Console.WriteLine("Normal\t" + swatch.Elapsed);

        }

        public static void testVector3c() {
            // diag
            Console.WriteLine("==== Test Vector3c ====");
            Vector3c sumc;
            Vector3c biasc = new Vector3c(1.0, 1.0, 1.0);
            Vector3c gainc = new Vector3c(1.0, 1.0, 1.0);
            Vector3c elemc = new Vector3c(1.0, 1.0, 1.0);

            // add
            sumc = new Vector3c();
            swatch.Reset();
            swatch.Start();
            for (uint i = 0; i < LOOP; i++) {
                sumc.add(elemc);
            }
            swatch.Stop();
            Console.WriteLine("Add\t" + swatch.Elapsed);

            // sub
            sumc = new Vector3c();
            swatch.Reset();
            swatch.Start();
            for (uint i = 0; i < LOOP; i++) {
                sumc.sub(elemc);
            }
            swatch.Stop();
            Console.WriteLine("Sub\t" + swatch.Elapsed);

            // mul
            sumc = elemc;
            swatch.Reset();
            swatch.Start();
            for (uint i = 0; i < LOOP; i++) {
                sumc.mul(gainc);
            }
            swatch.Stop();
            Console.WriteLine("Mul\t" + swatch.Elapsed);

            // div
            sumc = elemc;
            swatch.Reset();
            swatch.Start();
            for (uint i = 0; i < LOOP; i++) {
                sumc.div(gainc);
            }
            swatch.Stop();
            Console.WriteLine("Div\t" + swatch.Elapsed);

            //mac
            sumc = new Vector3c();
            swatch.Reset();
            swatch.Start();
            for (uint i = 0; i < LOOP; i++) {
                sumc.mac(gainc, elemc);
            }
            swatch.Stop();
            Console.WriteLine("Mac\t" + swatch.Elapsed);

            // dot
            double dotc;
            swatch.Reset();
            swatch.Start();
            for (uint i = 0; i < LOOP; i++) {
                dotc = elemc.dot(gainc);
            }
            swatch.Stop();
            Console.WriteLine("Dot\t" + swatch.Elapsed);

            // norm
            double distc;
            swatch.Reset();
            swatch.Start();
            for (uint i = 0; i < LOOP; i++) {
                distc = elemc.norm();
            }
            swatch.Stop();
            Console.WriteLine("Norm\t" + swatch.Elapsed);

            // normalize
            sumc = elemc;
            swatch.Reset();
            swatch.Start();
            for (uint i = 0; i < LOOP; i++) {
                sumc.normalize();
            }
            swatch.Stop();
            Console.WriteLine("Normal\t" + swatch.Elapsed);

        }
    }
}
